use anyhow::Result;
use std::{thread, sync::mpsc};
use std::sync::mpsc::channel;
use std::time::Duration;


const NUM_PRODUCES: i32 = 4;


#[derive(Debug)]
struct Message {
    index: i32,
    value: i32,

}

impl Message {
    fn new(index: i32, value: i32) -> Message {
        Message { index, value }
    }
}

fn main() {
    let (tx, rx) = channel();

    for i in 0..NUM_PRODUCES {
        let tx = tx.clone();
        thread::spawn(move || {
            producer(i, tx).expect("TODO: panic message")
        });

    }


    let consumer = thread::spawn( move || {
        for msg in rx.iter() {
            println!("Received: {:?}", msg);
        }
    });

    consumer.join().unwrap();


    // let aa = rx.recv().unwrap();


    // println!("aa is {:?}", aa)

}


fn producer(index: i32, tx: mpsc::Sender<Message>) -> Result<()> {
    loop {
        let value = rand::random::<i32>();
        tx.send(Message::new(index, value))?;
        thread::sleep(Duration::from_secs(1));
    }
}

